package com.jishuo.nontax.bfc.service;


import com.github.pagehelper.PageHelper;
import com.jishuo.base.bean.BaseResult;
import com.jishuo.base.bean.ErrorCodeEnum;
import com.jishuo.base.bean.Pagination;
import com.jishuo.base.config.NonTaxConfig;
import com.jishuo.base.dao.UserMapper;
import com.jishuo.base.service.SequenceService;
import com.jishuo.base.util.ExportSXSSFUtil;
import com.jishuo.base.util.MD5;
import com.jishuo.nontax.bean.message.SetDeductBackOut;
import com.jishuo.nontax.bean.vo.DeductVO;
import com.jishuo.nontax.bfc.dao.BankMapper;
import com.jishuo.nontax.bfc.dao.DeductMapper;
import com.jishuo.nontax.bfc.dao.PayerTypeMapper;
import com.jishuo.nontax.bfc.pzk.PzkService;
import com.jishuo.nontax.bfc.tlq.MessageFactory;
import com.jishuo.nontax.bfc.tlq.MessageService;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.simpleframework.xml.Serializer;
import org.simpleframework.xml.core.Persister;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @auther dinggaofei
 * @Date 2022/12/22 15:00
 */
@Service
public class DeductService {

    private static Logger logger = LoggerFactory.getLogger(DeductService.class);

    @Resource
    private DeductMapper deductMapper;
    @Resource
    private PayerTypeMapper payerTypeMapper;
    @Resource
    private MessageService messageService;
    @Resource
    private SequenceService sequenceService;
    @Resource
    private BankMapper bankMapper;
    @Resource
    private NonTaxConfig nonTaxConfig;
    @Resource
    private UserMapper userMapper;

    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    /**
     * @param deduct 批扣收入对象
     * @auther dinggaofei
     * @Date 2022/12/22 16:45
     * @description
     */
    public BaseResult setDeduct(DeductVO deduct) {
        try {
            deduct.setCantonid(payerTypeMapper.findCantonidByPayertypeid(deduct.getPayertypeid()));
            deduct.setUnitid(Long.valueOf(payerTypeMapper.findUnitidByPayertypeid(deduct.getPayertypeid())));
            deduct.setAccountname(bankMapper.findAccountNameByAccountCode(deduct.getAccountcode()));
            deduct.setSendtime(sdf.format(new Date()));
            if (deductMapper.findDeductCount(deduct) > 0) {
                deductMapper.updateDeduct(deduct);
            } else {
                deduct.setDeductid(sequenceService.getNextSeq("FSSTUDENTSEQ"));
                deductMapper.insertDeduct(deduct);
            }
        } catch (Exception e) {
            logger.info("失败：" + e.toString());
            return new BaseResult();
        }
        return new BaseResult();
    }

    /**
     * @param deduct 批扣收入对象
     * @auther dinggaofei
     * @Date 2022/12/23 8:33
     * @description 上传批扣业务的学生缴费信息
     */
    public BaseResult setNewDeduct(DeductVO deduct) {
        try {
            deduct.setAccountname(bankMapper.findAccountNameByAccountCode(deduct.getAccountcode()));
            deduct.setSendtime(sdf.format(new Date()));
            if (deductMapper.findDeductCount(deduct) > 0) {
                deductMapper.updateDeduct(deduct);
            } else {
                deduct.setDeductid(sequenceService.getNextSeq("FSSTUDENTSEQ"));
                deductMapper.insertDeduct(deduct);
            }
        } catch (Exception e) {
            logger.info("失败：" + e.toString());
            return new BaseResult();
        }
        return new BaseResult();
    }

    /**
     * @auther dinggaofei
     * @Date 2022/12/23 9:02
     * @description 根据账户和入账时间查询批扣收入信息, 修改成缴费状态
     */
    public BaseResult sendDeduct(String accountcode, String accountdate) {
        List<DeductVO> list = deductMapper.findSendDeduct(accountcode, accountdate);
        if (list.size() == 0) return new BaseResult();
        // 更新为已收款
        deductMapper.updateSendDeduct(accountcode, accountdate);
        // 发送
        try {
            long messageid = sequenceService.getNextSeq("ELEMESSAGESEQ");
            Object obj = MessageFactory.setDeduct(list);
            messageService.sendMessage("SETDEDUCT", messageid, obj, "2.0");

            // 写凭证
            if (nonTaxConfig.IS_Pzk) {
                PzkService.sendPzk("SETDEDUCTPZK", obj);
            }
        } catch (Exception e) {
            logger.info("发送批扣失败：" + e.toString(), e);
            return new BaseResult(ErrorCodeEnum.TLQ_ERR);
        }
        return new BaseResult();
    }

    /**
     * 批扣列表信息
     *
     * @param deductVO
     * @param pagination
     * @return
     */

    public List<DeductVO> findDeductPage(DeductVO deductVO, Pagination pagination) {

        if (pagination.getRows() > 0) PageHelper.startPage(pagination.getPage(), pagination.getRows());
        List<DeductVO> deductPage = this.deductMapper.findDeductPage(deductVO);
        return deductPage;
    }

    /**
     * 修改批扣信息
     *
     * @param deductVO
     * @return
     */
    public BaseResult saveDeduct(DeductVO deductVO) {
        int n = deductMapper.saveDeduct(deductVO);
        if (n < 1) return new BaseResult(ErrorCodeEnum.DB_ERR);
        return new BaseResult();
    }

    /**
     * 根据id 获取批扣信息
     *
     * @param deductid
     * @return
     */
    public DeductVO getDeduct(Long deductid) {
        return deductMapper.getDeduct(deductid);
    }

    /**
     * 发送批扣信息
     *
     * @param billids
     * @param userpwd
     * @param usercode
     * @return
     */
    public BaseResult findSendDeduct(List<String> billids, String userpwd, String usercode) {
        if (userMapper.getUserCount(MD5.md5s(userpwd), usercode) > 0) {
            if (billids != null && billids.size() > 0) {
                List<DeductVO> deductPage = deductMapper.findDeduct(billids);
                for (DeductVO vos : deductPage
                ) {
                    return sendDeductByID(vos);
                }

            } else {
                return new BaseResult(ErrorCodeEnum.CUSTOM_ERR.getCode(), "单据不存在");
            }
        } else {
            return new BaseResult(ErrorCodeEnum.CUSTOM_ERR.getCode(), "用户信息验证失败");
        }
        return new BaseResult(ErrorCodeEnum.UNKNOWN_ERR);
    }

    private BaseResult sendDeductByID(DeductVO deductVO) {
        deductVO.setSendtime(sdf.format(new Date()));
        try {
            long messageid = sequenceService.getNextSeq("ELEMESSAGESEQ");
            int n = deductMapper.updateSendbankaffirm(deductVO);
            if (n < 1) {
                return new BaseResult(ErrorCodeEnum.DB_ERR.getCode(), "保存批扣失败");
            }
            List<DeductVO> list = new ArrayList<>();
            list.add(deductVO);
            Object obj = MessageFactory.setDeduct(list);
            messageService.sendMessage("SETDEDUCT", messageid, obj, "2.0");
        //写凭证
            if (nonTaxConfig.IS_Pzk)
            {
                PzkService.sendPzk("SETDEDUCTPZK",obj);
            }
        }catch (Exception e) {
            logger.info("处理获取批扣失败。" + e.toString());
            return new BaseResult(ErrorCodeEnum.TLQ_ERR);
        }

        return  new BaseResult();
    }

    /**
     * 冲销批扣信息
     *
     * @param
     * @param userpwd
     * @param usercode
     * @return
     */
    public BaseResult cleanDeduct(List<String> billids, String userpwd, String usercode) {
        String errinfo = "";
        try {
            if (userMapper.getUserCount(MD5.md5s(userpwd), usercode) > 0) {
                if (billids != null && billids.size() > 0) {
                    for (int i = 0; i < billids.size(); i++) {

                    }
                    List<DeductVO> deductPage = deductMapper.findDeduct(billids);
                    for (DeductVO vos : deductPage
                    ) {
                            setDivideBackOut(vos);
                            deductMapper.updateIsBankAffirm(vos.getDeductid());
                    }
                        errinfo = "冲销成功";
                        return new BaseResult(ErrorCodeEnum.SUCCESS.getCode(), errinfo);

                } else {
                    return new BaseResult(ErrorCodeEnum.CUSTOM_ERR.getCode(), "单号不存在");
                }
            } else {
                return new BaseResult(ErrorCodeEnum.CUSTOM_ERR.getCode(), "用户信息验证失败");
            }
        } catch (Exception e) {
            return new BaseResult(ErrorCodeEnum.UNKNOWN_ERR);
        }
    }


    private BaseResult setDivideBackOut(DeductVO vos) {
        //xml解析器
        Serializer serializer = new Persister();
        //xml转换器
        StringWriter sw = new StringWriter();
        try {
            Long messageid = sequenceService.getNextSeq("ELEMESSAGESEQ");
            SetDeductBackOut obj = (SetDeductBackOut) MessageFactory.getSetDeductBackOut(vos);
            obj.setRemark("");
            obj.setBackoutname("");
            serializer.write(obj, sw);
            messageService.sendMessage("SETDEDUCTBACKOUT", messageid, obj, "2.0");
            if (nonTaxConfig.IS_Pzk) {
                PzkService.sendPzk("SETDEDUCTBACKOUTPZK", obj);
            }
        } catch (Exception e) {
            logger.info("批扣失败：" + e.toString());
            return new BaseResult(ErrorCodeEnum.TLQ_ERR);
        }
        return new BaseResult();
    }

    /**
     * 导出批扣信息
     *
     * @param billids
     * @param response
     * @return
     */
    public void deductExport(List<String> billids, HttpServletResponse response) {

        List<DeductVO> deductPage = deductMapper.findDeduct(billids);
        String[] headers = {"流水号", "行政区划", "区划编码", "区划名称", "单位id", "单位（部门）编码", "单位（部门）名称", "银行名称", "账户名称", "账号", "付款人", "付款人账号", "付款人账户名称", "金额", "附言", "银行交易流水号", "银行网点", "入账日期", "单据状态", "入账时间", "发送时间", "__status", "是否发送"};
        String[] col = {"deductid", "cantonid", "cantoncode", "cantonname", "unitid", "unitcode", "unitname", "payeebankname", "payeeaccountname", "payeeaccountcode", "payeraccountcode", "payeraccountname", "fund", "postscript", "bankaffirm", "bankstation", "accountdate", "billstate", "accounttime", "sendtime", "", "issend"};
        ExportSXSSFUtil ex = new ExportSXSSFUtil();
        SXSSFWorkbook workbook = ex.exportExcelSXSSF("批扣列表", headers, col, deductPage, null);
        response.setContentType("application/vnd.ms-excel");
        try {
            response.setHeader("Content-Disposition", "attachment;filename=" +
                    new String(("批扣列表.xls").getBytes(), "iso-8859-1"));
            OutputStream ouputStream = response.getOutputStream();
            workbook.write(ouputStream);
            ouputStream.flush();
            ouputStream.close();
        } catch (Exception e) {
            logger.info("导出失败：" + e.toString());
        }

    }
}
